package com.heima.comment.service.impl;

import com.heima.apis.user.IUserClient;
import com.heima.comment.pojos.ApComment;
import com.heima.comment.pojos.ApCommentLike;
import com.heima.comment.service.ArticleCommentService;
import com.heima.common.aliyun.GreenTextScan;
import com.heima.common.constants.CommentConstants;
import com.heima.common.redis.CacheService;
import com.heima.model.comment.dto.CommentLikeDto;
import com.heima.model.comment.dto.CommentListDto;
import com.heima.model.comment.dto.CommentSaveDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.pojos.ApUser;
import com.heima.utils.thread.ApThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
@Transactional
public class ArticleCommentServiceImpl implements ArticleCommentService {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private IUserClient userClient;
    @Autowired
    private GreenTextScan textScan;
    @Autowired
    private CacheService cacheService;

    /**
     * 保存文章评论
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult saveComment(CommentSaveDto dto) {
        //校验是否登录
        ApUser apUser = ApThreadLocalUtil.getApUser();
        if (apUser == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //校验参数
        if (dto == null || dto.getContent() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //评论大于140字
        if (dto.getContent().length()>140){
            return ResponseResult.errorResult(AppHttpCodeEnum.COMMENT_TOO_MORE);
        }
        //进行评论的文本反垃圾检测
        boolean flag = checkComment(dto.getContent());
        if (flag) {
            ApComment articleComment = new ApComment();
            //设置属性
            articleComment.setAuthorId(apUser.getId());
            articleComment.setContent(dto.getContent());
            articleComment.setCreatedTime(new Date());
            articleComment.setEntryId(dto.getArticleId());
            //feign调用user微服务   查询用户名
            ResponseResult responseResult = userClient.selectUser(apUser.getId());
            if (responseResult.getCode() == 200) {
                String userName = (String) responseResult.getData();
                //设置用户名
                articleComment.setAuthorName(userName);
                //将内容保存到MongoDB中
                mongoTemplate.save(articleComment);
                return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
            } else {
                return responseResult;
            }
        } else {
            return ResponseResult.errorResult(AppHttpCodeEnum.COMMENT_FAIL);
        }

    }

    /**
     * 展示文章评论列表
     *
     */
    @Override
    public ResponseResult commentList(CommentListDto dto) {
        //校验参数
        if (dto == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        List<ApComment> apComments = null;

        //从线程中取用户id
        ApUser apUser = ApThreadLocalUtil.getApUser();
        if (apUser != null) {
            Query query =null;
            //如果是第一次展示   就展示最新10条
            if (dto.getIndex().equals(1)) {
                query = Query.query(Criteria.where("entryId").is(dto.getArticleId())
                        //打开评论才能查看
                                    .and("flag").is(0))
                        .with(Sort.by(Sort.Direction.DESC, "createdTime"))
                        .limit(10);
            } else {
                //往下翻页
                query = Query.query(Criteria.where("entryId").is(dto.getArticleId())
                        .and("flag").is(0)
                        .andOperator(Criteria.where("createdTime").lt(dto.getMinDate())))
                        .with(Sort.by(Sort.Direction.DESC, "createdTime"))
                        .limit(10);
            }
            apComments = mongoTemplate.find(query, ApComment.class);
            if (apComments!=null) {
                apComments=setOperationByRedis(apComments, apUser);
            }
        }
        return ResponseResult.okResult(apComments);
    }

    /**
     * 点赞设置
     * @param apComments
     * @param apUser
     * @return
     */
    private List<ApComment> setOperationByRedis(List<ApComment> apComments, ApUser apUser) {
        List<ApComment> apCommentList=new ArrayList<>();
        for (ApComment apComment : apComments) {
            Object result = cacheService.hGet(CommentConstants.COMMENT_LIKES + apUser.getId(),
                    apComment.getId());
            if (result != null) {
                apComment.setOperation(0);
            }
            apCommentList.add(apComment);
        }
        return apCommentList;
    }

    /**
     * 点赞
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult commentLike(CommentLikeDto dto) {
        //校验参数
        if (dto == null || dto.getCommentId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //判断是否登录
        ApUser apUser = ApThreadLocalUtil.getApUser();
        if (apUser == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        ApCommentLike apCommentLike = new ApCommentLike();
        apCommentLike.setAuthorId(apUser.getId());
        apCommentLike.setCommentId(dto.getCommentId());
        //将内容保存到mongodb中
        mongoTemplate.save(apCommentLike);
        if (dto.getOperation().equals(0)) {
            //将点赞的数据保存在redis
            cacheService.hPut(CommentConstants.COMMENT_LIKES + apUser.getId(),
                    dto.getCommentId(), dto.getOperation().toString());
            Query query = new Query(Criteria.where("_id").is(dto.getCommentId()));
            ApComment apComment = mongoTemplate.findOne(query, ApComment.class);
            Integer likes = apComment.getLikes();
            if (likes == null || likes == 0) {
                apComment.setLikes(1);
            } else {
                apComment.setLikes(++likes);
            }
            mongoTemplate.save(apComment);
        } else {
            //取消点赞
            cacheService.hDelete(CommentConstants.COMMENT_LIKES + apUser.getId(),
                    dto.getCommentId());
            Query query = new Query(Criteria.where("_id").is(dto.getCommentId()));
            ApComment apComment = mongoTemplate.findOne(query, ApComment.class);
            Integer likes = apComment.getLikes();
            apComment.setLikes(--likes);
            mongoTemplate.save(apComment);
            //删除喜欢列表
            Query query1=new Query(Criteria.where("commentId").is(dto.getCommentId())
                                .andOperator(Criteria.where("authorId").is(apUser.getId())));
            mongoTemplate.remove(query1,ApCommentLike.class);
        }

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 评论文本反垃圾检测
     *
     * @param comment
     * @return
     */
    private boolean checkComment(String comment) {
        boolean flag = true;
        try {
            Map map = textScan.greeTextScan(comment);
            if (map != null) {
                if (map.get("suggestion").equals("block"))
                    flag = false;
                if (map.get("suggestion").equals("review"))
                    flag = false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }
}
